﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace converter.template.item
{
    public sealed class DataSet
    {
        public class Field
        {
            // If isExpression is true then the value should be evaluated
            // otherwise it contains a field name.
            public Field(string name, string value, bool isExpression)
            {
                this.name = name;
                this.value = value;
                this.isExpression = isExpression;
            }

            public string Name
            {
                get
                {
                    return name;
                }
            }

            public string Value
            {
                get
                {
                    return value;
                }
            }

            private readonly string name;
            private readonly string value;
            private readonly bool isExpression;
        }

        public class Query
        {
            public Query(string dataSourceName, string commandText, List<QueryParameter> parameters)
            {
                this.dataSourceName = dataSourceName;
                this.parameters = parameters;

                this.commandText = commandText
                    .Replace("'", "&apos;")
                    .Replace("\"", "&quot;")
                    .Replace("\n", "&#x0D;&#x0A;")
                    .Replace(">", "&gt;")
                    .Replace("<", "&lt;");
                foreach (QueryParameter parameter in parameters)
                {
                    string pattern = "@" + parameter.GetName();
                    this.commandText = this.commandText.Replace(pattern, string.Format("${{{0}}}", parameter.GetName()));
                }
            }

            public string GetCommandText()
            {
                return commandText;
            }

            public string GetDataSourceName()
            {
                return dataSourceName;
            }

            private readonly string dataSourceName;
            private readonly string commandText;
            private readonly List<QueryParameter> parameters;
        }

        public class QueryParameter
        {
            public QueryParameter(string name, string value)
            {
                this.name = name;
                this.value = value;
            }

            public string GetName()
            {
                return name;
            }

            private readonly string name;
            private readonly string value;
        }

        public DataSet(string name, Query query, List<Field> fields)
        {
            this.name = name;
            this.query = query;
            this.fields = fields;
        }

        public string GetCommandText()
        {
            return query.GetCommandText();
        }

        public string GetDataSourceName()
        {
            return query.GetDataSourceName();
        }

        public Field GetField(string name)
        {
            return fields.Find(
                delegate(Field f)
                {
                    return f.Name == name;
                }
                );
        }

        private readonly string name;
        private readonly Query query;
        private readonly List<Field> fields;
    }
}
